Imports System.Xml


Public Class XMLCriteriaProvider
    Implements ICriteriaProvider

    Private Const XML_ELEMENT_CRITERION As String = "Criterion"
    Private Const XML_ELMNT_NAME As String = "Name"
    Private Const XML_ELMNT_SQL_NAME As String = "SQLFieldName"
    Private Const XML_ELMNT_HELP_TEXT As String = "HelpText"
    Private Const XML_ELMNT_CTRL_UI_TYPE As String = "ControlUIType"
    Private Const XML_ELMNT_LBL_TEXT As String = "LabelText"
    Private Const XML_ELMNT_MANDATORY As String = "IsMandatory"
    Private Const XML_ELMNT_MANDATORY_2 As String = "IsMandatory2"
    Private Const XML_ELMNT_READ_ONLY As String = "IsReadOnly"
    Private Const XML_ELMNT_READ_ONLY_2 As String = "IsReadOnly2"
    Private Const XML_ELMNT_IS_HIDDEN As String = "IsHidden"
    Private Const XML_ELMNT_WIDTH As String = "Width"
    Private Const XML_ELMNT_TRANSIENT As String = "IsTransient"
    Private Const XML_EMNT_COMBO_DATA_SOURCE As String = "ComboBoxDataSource"
    Private Const XML_EMNT_SQL_OPERATOR As String = "SqlOperator"
    Private Const XML_EMNT_SQL_EXPRESSION As String = "SqlExpression"
    Private Const XML_EMNT_CRITERION_PROCESSOR As String = "ICriterionProcessor"

    Private Const STR_1 As String = "1"
    Private Const STR_ON As String = "on"

    Public Function loadCriteriaControls(ByVal source As Object) As List(Of CriterionMetadata) _
                Implements ICriteriaProvider.loadCriteriaDefinitions

        Dim reportsElement As XmlElement = CType(source, XmlElement)

        Dim criteria As New List(Of CriterionMetadata)
        Dim cnodes As XmlNodeList = reportsElement.GetElementsByTagName(XML_ELEMENT_CRITERION)

        For Each xnode As XmlNode In cnodes

            Dim critElement As XmlElement = CType(xnode, XmlElement)
            Dim c As New CriterionMetadata
            Dim node As XmlNode

            node = critElement.SelectSingleNode(XML_ELMNT_NAME)
            If node IsNot Nothing Then
                c.Name = node.InnerText
            End If

            node = critElement.SelectSingleNode(XML_ELMNT_SQL_NAME)
            If node Is Nothing Then
                c.SqlFieldName = c.Name
            Else
                c.SqlFieldName = node.InnerText
            End If

            node = critElement.SelectSingleNode(XML_ELMNT_HELP_TEXT)
            If node IsNot Nothing Then
                c.helpText = node.InnerText
            End If


            node = critElement.SelectSingleNode(XML_EMNT_SQL_EXPRESSION)
            If node IsNot Nothing Then
                c.SqlExpression = node.InnerText
            End If

            node = critElement.SelectSingleNode(XML_EMNT_CRITERION_PROCESSOR)
            If node IsNot Nothing Then
                Dim lTypeGetType As Type = Type.GetType(node.InnerText)
                c.criterionWhereClauseBuilder = CType(Activator.CreateInstance(lTypeGetType), ICriterionProcessor)
            End If


            node = critElement.SelectSingleNode(XML_EMNT_SQL_OPERATOR)
            If node IsNot Nothing Then
                c.SqlOperator = node.InnerText
            End If

            node = critElement.SelectSingleNode(XML_ELMNT_WIDTH)
            If node IsNot Nothing Then
                c.width = CInt(node.InnerText)
            End If

            node = critElement.SelectSingleNode(XML_ELMNT_TRANSIENT)
            If node IsNot Nothing Then
                c.isTransient = CBool(IIf(node.InnerText = STR_1 _
                                            OrElse node.InnerText.ToLower = STR_ON, _
                            True, False))
            End If

            node = critElement.SelectSingleNode(XML_ELMNT_IS_HIDDEN)
            If node IsNot Nothing Then
                c.isHidden = CBool(IIf(node.InnerText = STR_1 _
                                            OrElse node.InnerText.ToLower = STR_ON, _
                            True, False))
            End If

            node = critElement.SelectSingleNode(XML_ELMNT_CTRL_UI_TYPE)
            If node IsNot Nothing Then
                c.controlUIType = CType(node.InnerText, enumReportCriterionUIType)
            End If

            node = critElement.SelectSingleNode(XML_ELMNT_LBL_TEXT)
            If node IsNot Nothing Then
                c.labelText = node.InnerText
            End If

            node = critElement.SelectSingleNode(XML_ELMNT_MANDATORY)
            If node IsNot Nothing Then
                c.isMandatory = CBool(IIf(node.InnerText = STR_1 _
                                            OrElse node.InnerText.ToLower = STR_ON, _
                            True, False))
            End If

            node = critElement.SelectSingleNode(XML_ELMNT_MANDATORY_2)
            If node IsNot Nothing Then
                c.isMandatory2 = CBool(IIf(node.InnerText = STR_1 _
                                            OrElse node.InnerText.ToLower = STR_ON, _
                            True, False))
            Else
                'take the first control's mandatory setting
                c.isMandatory2 = c.isMandatory
            End If

            node = critElement.SelectSingleNode(XML_ELMNT_READ_ONLY)
            If node IsNot Nothing Then
                c.isReadOnly = CBool(IIf(node.InnerText = STR_1 _
                                            OrElse node.InnerText.ToLower = STR_ON, _
                            True, False))
            End If

            node = critElement.SelectSingleNode(XML_ELMNT_READ_ONLY_2)
            If node IsNot Nothing Then
                c.isReadOnly = CBool(IIf(node.InnerText = STR_1 _
                                            OrElse node.InnerText.ToLower = STR_ON, _
                            True, False))
            End If

            node = critElement.SelectSingleNode("DefaultValue")
            If node IsNot Nothing Then
                c.defaultValue = node.InnerText
            End If

            node = critElement.SelectSingleNode("IsRange")
            If node IsNot Nothing Then
                c.isRange = CBool(IIf(node.InnerText = STR_1 _
                                            OrElse node.InnerText.ToLower = STR_ON, _
                            True, False))
            End If

            node = critElement.SelectSingleNode("LabelText2")
            If node IsNot Nothing Then
                c.labelText2 = node.InnerText
            End If

            node = critElement.SelectSingleNode("DefaultValue2")
            If node IsNot Nothing Then
                c.defaultValue2 = node.InnerText
            End If

            node = critElement.SelectSingleNode(XML_EMNT_COMBO_DATA_SOURCE)
            If node IsNot Nothing Then
                c.comboBoxDataSource = node.InnerText
            End If



            If String.IsNullOrEmpty(c.Name) Then
                Throw New ApplicationException("There is a CriterionControl without a ""Name"" Element, or with a blank ""Name"" element.")
            End If

            criteria.Add(c)

        Next

        Return criteria

    End Function

End Class